//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// lru_replacer.cpp
//
// Identification: src/buffer/lru_replacer.cpp
//
// Copyright (c) 2015-2019, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "buffer/lru_replacer.h"
#include <cassert>

namespace bustub {

   
    /**
    LRUReplacer implements the lru replacement policy
    **/
    LRUReplacer::LRUReplacer(size_t num_pages) {
        capacity = num_pages;
    }

    LRUReplacer::~LRUReplacer() = default;

    bool LRUReplacer::Victim(frame_id_t *frame_id) { 
        replacer_mutex.lock();
        if(lru_map.empty()){
            replacer_mutex.unlock();
            return false;
        }

        frame_id_t victim_frame = lru_list.back();
        lru_map.erase(victim_frame);

        lru_list.pop_back();
        *frame_id = victim_frame;
        replacer_mutex.unlock();
        return true; 
        
    }

    void LRUReplacer::Pin(frame_id_t frame_id) {
        replacer_mutex.lock();
        //被引用的frame不能出现lru list
        if(lru_map.count(frame_id) != 0){
            lru_list.erase(lru_map[frame_id]);
            lru_map.erase(frame_id);
        }
        
        replacer_mutex.unlock();
    }

    void LRUReplacer::Unpin(frame_id_t frame_id) {
        replacer_mutex.unlock();
        if(lru_map.count(frame_id) != 0){
             replacer_mutex.unlock();
             return ;
        }   

        //新加入的放到头节点，如果容量满了，需要删除尾节点
        while(Size() > capacity){
            frame_id_t need_del = lru_list.back();
            lru_list.pop_back();
            lru_map.erase(need_del);
        }

        //insert
        lru_list.push_front(frame_id);
        lru_map[frame_id] = lru_list.begin();

        replacer_mutex.unlock();
        
    }

    size_t LRUReplacer::Size() { return lru_map.size(); }



}  // namespace bustub
